Step 1Database Privilege Revocation & Assignment
When setting up a WordPress subdomain site, it's crucial to follow the principle of least privilege. This means revoking all database privileges from the database user and then assigning only the essential privileges needed for the site to function correctly.
1.1 Identify Database Credentials
Before modifying privileges, you need to extract the database name and username from your WordPress configuration file. Use the grep command to retrieve this information:
sudo grep DB_NAME /var/www/sub.example.com/public_html/wp-config.php
This command will return the database name. To get the database username, modify the command:
sudo grep DB_USER /var/www/sub.example.com/public_html/wp-config.php
1.2 Revoke All Database Privileges
After identifying the credentials, log into MariaDB and revoke all privileges from the user on the specified database. This ensures a clean slate before assigning specific permissions.
sudo mysql -u root -p
Once logged into MariaDB, execute the following command to revoke all privileges:
REVOKE ALL PRIVILEGES ON database_name.* FROM 'database_user'@'localhost';
database_name with your actual database name and
database_user with your actual username. The asterisk (*) applies the revocation to all
tables within the database.
1.3 Grant Essential Privileges
After revoking all privileges, grant only the specific privileges required for WordPress to function properly. The essential privileges are SELECT, INSERT, UPDATE, and DELETE.
GRANT SELECT, INSERT, UPDATE, DELETE ON database_name.* TO 'database_user'@'localhost';
| Privilege | Purpose | Required for WordPress |
|---|---|---|
| SELECT | Read data from database tables | β Essential |
| INSERT | Add new records to database tables | β Essential |
| UPDATE | Modify existing records in database tables | β Essential |
| DELETE | Remove records from database tables | β Essential |
| CREATE | Create new tables or databases | β οΈ Plugin-dependent |
| DROP | Delete tables or databases | β οΈ Plugin-dependent |
| ALTER | Modify table structure | β οΈ Plugin-dependent |
1.4 Apply Changes and Exit
After granting the necessary privileges, flush the privilege tables to ensure changes take effect immediately:
FLUSH PRIVILEGES;
Exit MariaDB:
exit
Step 2File Ownership & Permissions Management
Proper file ownership and permissions are critical for WordPress security. We'll use bash scripts to manage permissions efficiently during site administration and after updates.
2.1 Prepare Update Scripts
Navigate to your bash scripts directory:
cd ~/wp_bash_scripts/
Copy existing scripts for your subdomain site:
cp pre-update_example.wp pre-update_sub.example.com.wp
cp post-update_example.wp post-update_sub.example.com.wp
2.2 Modify Pre-Update Script
Edit the pre-update script to match your subdomain configuration:
nano pre-update_sub.example.com.wp
Make the following changes:
- Update the PHP-FPM pool user to match the user created for this subdomain
- Change the domain name to your subdomain (e.g., sub.example.com)
Save and close the file (Ctrl+X, then Y, then Enter).
2.3 Modify Post-Update Script
Edit the post-update script similarly:
nano post-update_sub.example.com.wp
Make the same changes as the pre-update script:
- Update the PHP-FPM pool user
- Change the domain name to your subdomain
Save and close the file.
2.4 Understanding Script Impact
Files: Read + Write (User & Group)
Directories: Read + Write + Execute (User & Group)
Core Files: Read-only
Core Directories: Read + Execute only
wp-content: Read + Write (maintained)
View current permissions before running scripts:
ls -l /var/www/sub.example.com/public_html/
2.5 Execute Post-Update Script
Run the post-update script to apply hardened permissions:
bash post-update_sub.example.com.wp
Verify the changes:
ls -l /var/www/sub.example.com/public_html/
You'll observe that:
- Core WordPress files and directories no longer have write permissions
- Only the wp-content directory retains write permissions
- This prevents unauthorized modifications to core WordPress files
2.6 Execute Pre-Update Script
When performing site administration tasks, run the pre-update script:
bash pre-update_sub.example.com.wp
This restores write permissions temporarily, allowing issue-free site administration.
ls -l /var/www/sub.example.com/public_html/
- During Setup: Run pre-update script for unrestricted administration
- After Setup: Run post-update script to harden permissions
- Before Updates: Run pre-update script
- After Updates: Run post-update script
Step 3Installation Completion Checklist
At this stage, your subdomain site installation is nearly complete. Here's what has been accomplished:
| Security Measure | Status | Notes |
|---|---|---|
| Database Privilege Management | β Complete | Least privilege principle applied |
| File Ownership & Permissions | β Complete | Scripts configured and ready |
| PHP-FPM Pool Configuration | β Complete | Isolated user per site |
| Nginx Server Block | β Complete | HTTP/2, HTTP/3, SSL configured |
| SSL Certificate (Wildcard) | β Complete | Valid for all subdomains |
| Rate Limiting | β Complete | wp-login.php and xmlrpc.php protected |
| Web Application Firewall | β³ Pending | Plugin configuration needed |
| REST API Restrictions | β³ Pending | Disable for non-logged-in users |
| Hotlinking Protection | π Reference First Site | See primary site configuration |
| Disallow File Modifications | π Reference First Site | See primary site configuration |
3.1 Remaining Tasks
- Web Application Firewall: Configure WAF plugin settings
- REST API Security: Install and configure plugin to disable REST API for non-authenticated users
Step 4Next Phase: Optimization
With the subdomain site secured, the next phase focuses on optimization to ensure maximum performance:
Best PracticesSecurity Maintenance Guidelines
Regular Security Audits
- Weekly: Review access logs for suspicious activity
- Monthly: Update WordPress core, themes, and plugins
- Quarterly: Review and audit database user privileges
- Annually: Conduct comprehensive security assessment
Permission Management Workflow
- Always run pre-update script before making administrative changes
- Perform necessary updates or modifications
- Immediately run post-update script after completion
- Verify changes with
ls -lcommand - Test site functionality thoroughly
Database Security Tips
- Never grant unnecessary privileges to database users
- Use strong, unique passwords for database users
- Regularly backup databases before major changes
- Monitor database query logs for anomalies
- Keep MariaDB/MySQL updated to latest stable version